
<script setup>
	
	import spellApi from '@/common/apis/spell';
	import wordWifi from './components/wifi.vue';
	import popupCard from './components/popup-card.vue';
	import wordTimedown from './components/timedown.vue';
	import { ref, nextTick, onBeforeUnmount } from 'vue';
	
	
	/** 导航栏 margin-right */
	const navRight = ref(0);
	
	// #ifdef MP-WEIXIN
	/** 获取小程序胶囊信息 */
	const { width } = uni.getMenuButtonBoundingClientRect()
	navRight.value = `${width}px`;
	// #endif
	
	/** 当前项索引 */
	const playIndex = ref(0);
	
	/** 词汇列表 */
	const vocabularylist = ref(uni.getStorageSync('_vocabulary-list'));
	
	/** 拼写单词 */
	const spellWord = ref();
	const currentWord = ref(uni.getStorageSync('_current-word'));
	const wordInfo = ref({});
	const setWord = () => {
		isHint.value = false;
		selectWord.value = {};
		const _spellValue = wordInfo.value.syllableChars.reduce((str, key) => {
			const _str = `${key === wordInfo.value.rightAnswer.content ? '_' : key}`;
			str += _str;
			return str;
			
		}, '');
		
		spellValue.value = wordInfo.value.isCombine ? wordInfo.value.stem.reduce((str, key) => str += key + '·', '').slice(0, -1) : _spellValue;
		spellWord.value = wordInfo.value.isCombine ? wordInfo.value.syllableChars.reduce((str, key) => str += key + '·', '').slice(0, -1) : currentWord.value.word;
	};
	const getWordInfo = async () => {
		const result = await spellApi.splitWord({ word: currentWord.value.word });
		wordInfo.value = result;
		setWord();
	};
	getWordInfo();
	
	
	/** 拼写数据 */
	const spellData = uni.getStorageSync('_spell-data');
	
	/** 是否提示 */
	const isHint = ref(false);
	
	/** 是否播放单词 */
	const isPlayWord = ref(false);
	
	/** 播放结束 */
	const playEnd = () => {
		isPlayWord.value = false;
	};
	
	/** 监听自然结束 */
	uni.useAudio.onEnded(playEnd);
	
	/** 监听播放暂停 */
	uni.useAudio.onStop(playEnd);
	
	/** 播放单词 */
	const onPlayWord = () => {
		isPlayWord.value = true;
		uni.useAudio.src(currentWord.value?.voiceFile?.url);
	};
	
	
	/** 倒计时组件 */
	const wordTimedownRef = ref({});
	
	/** 拼写值 */
	const spellValue = ref('');
	
	/** 提交函数 */
	const _submit = async () => {
		await spellApi.saveWords({ words: [{ id: currentWord.value.id, isSpell: 1 }], logId: spellData.logId });
		uni.setStorageSync('-spell-time', wordTimedownRef.value?.times);
		uni.navigateBack();
	};
	
	/** shake */
	const shake = ref(false);
	
	
	/** 拼写常量 */
	const SPELL_COLOR = {
		/** 不在原单词范围内 */
		NO: '#8e888b',
		
		/** 错误 */
		ERROR: '#e16857',
		
		/** 正确 */
		CORRECT: '#00c386'
	};
	
	/** 提交 */
	const onSubmit = async () => {
		isHint.value = true;
		if (!spellValue.value) return;
		if (selectWord.value.prefix !== wordInfo.value.rightAnswer.prefix) {
			shake.value = true;
			setTimeout(() => shake.value = false, 800)
			return;
		};
		
		_submit();
	};
	
	/** 倒计时结束 */
	const onTimedown = () => {
		uni.$fui.modal({
			title: '提示',
			success: _submit,
			showCancel: false,
			content: '本单词拼写时间已到，请提交拼写'
		});
	};
	
	/** 是否显示答题卡 */
	const showPopupCard = ref(false);
	
	/** 打开复习卡 */
	const openCard = () => {
		inputFocus.value = false;
		showPopupCard.value = true;
	};
	
	/** 缓存计时 */
	const onInterval = time => {
		uni.setStorageSync('_interval', time);
	};
	
	
	/** 拼写 */
	const selectWord = ref({});
	const onSpell = word => {
		if (selectWord.value.content) return;
		selectWord.value = word;
		const findIndex = spellValue.value.indexOf('_');
		if (!!~findIndex) {
			spellValue.value = spellValue.value.replace('_', `<span style="color: ${SPELL_COLOR[word.content === wordInfo.value.rightAnswer.content ? 'CORRECT' : 'ERROR']}">${word.content}</span>`);
			onSubmit();
		};
	};
	
	
</script>

<template>
	<view class="containerbox">
		<uv-navbar auto-back placeholder bg-color="transparent">
			<template #right>
				<view :style="{ marginRight: navRight }" class="flex">
					<view class="flex flex-column justify-center items-center mr-15">
						<image :src="`${$imageBaseUrl}time.png`" class="h-25" style="width: 58rpx" />
						<word-timedown size="18" :flash="false" @time-fun="onTimedown" ref="wordTimedownRef" @onInterval="onInterval" />
					</view>
					
					<view class="w-50 mr-10">
						<uv-image :src="`${$imageBaseUrl}card.png`" width="50rpx" height="50rpx" @tap="openCard" />
					</view>
				</view>
			</template>
		</uv-navbar>
		
		
		<view class="text-center w-full mt-300 bold" :class="{ shake }">
			<view class="rich-text-view h-108 text-80">
				<rich-text :nodes="spellValue" />
			</view>
 		</view>
		
		
		<view class="text-center bold mt-50 px-50">
			<view class="text-80" v-if="isHint">{{ spellWord }}</view>
			<view v-else class="text-26">{{ currentWord.translation }}</view>
		</view>
		
		
		<view class="mt-auto px-50 flex items-center flex-wrap justify-between text-40">
			<view 
				:key="index"
				@tap="onSpell(word)"
				v-for="word, index in wordInfo?.options"
				class="flex items-center justify-center word-content mb-25"
				style="width:200rpx;height:120rpx;box-shadow:0 0 5rpx #eee;border-radius:12rpx;transition:all .3s"
				:style="{ backgroundColor: selectWord.content === word.content ? 'rgba(26,188,156,.5)' : 'rgba(255,255,255,.5)' }"
			>
				{{ word.content }}
			</view>
		</view>
		
		
		<view class="flex items-center justify-between px-50 pb-80 pt-55 text-48">
			<view 
				@tap="isHint = !isHint" 
				hover-class="botton-active"
				:class="{ selected: isHint }"
				class="spell spell-tishi w-90 h-90 bgc-white round-30 flex items-center justify-center transition-bg" 
			/>
			
			<view @tap="onPlayWord" class="relative w-90 h-90 bgc-white round-30 flex items-center justify-center text-30 transition-bg" hover-class="botton-active" v-if="!isPlayWord">
				<view class="absolute" style="left: 40rpx; top: 20rpx; transform: scale(1.2)">
					<word-wifi color="#00c386" />
				</view>
			</view>
			
			<text class="px-30 h-90 bgc-white round-30 flex items-center justify-center text-30 normal text-9ca2a0" v-else>/rI'kwest/</text>
			
			<view class="w-90 h-90 bgc-white round-30 flex items-center justify-center transition-bg" hover-class="botton-active" @tap="setWord">
				<uv-icon name="reload" size="46rpx" color="#000" />
			</view>
		</view>
		
		<popup-card :list="vocabularylist" v-model="showPopupCard" :current="vocabularylist.findIndex(item => item.id === currentWord.id)" :button="false" />
	</view>
</template>


<style>
	page {
		background: linear-gradient(165deg, #c4f2e7, #f5f8e5, #f1f1f1, #f1f1f1);
	}
</style>

<style scoped lang="scss">
	.top-0{top: 0}
	.h-108{height: 108rpx}
	.overflow-hidden{overflow: hidden}
	.inout-view::placeholder{font-weight: normal;font-size: 50}
	.mt-300{margin-top: 300rpx}
	.mt-auto{margin-top: auto}
	.opacity-70{opacity: .7;transition:  opacity .3s}
	.spell{transition: color .3s}
	.selected{color: #00c386}
	.normal{font-weight: normal}
	.text-9ca2a0{color: #9ca2a0}
	.mt-6{margin-top: 6rpx}
	.transition-bg{transition: background-color .3s}
	.botton-active{background-color: #f0f0ee}
	.transition-height{transition: height .25s}
	.rich-text-view{position: relative;width: fit-content;margin: 0 auto}
	.rich-text-view-cursor-blinks{position: absolute;right: -5rpx;top: 0;width: 5rpx;height: 100%;background-color: #00c386; animation: cursor-blinks 800ms infinite steps(1, start)}
	.shake{animation: shake 800ms ease-in-out;transform-style: preserve-3d}
	
	 @keyframes shake{
		10%,90%{transform: translate3d(-1px, 0, 0)}
		20%,80%{transform: translate3d(+2px, 0, 0)}
		30%,70%{transform: translate3d(-4px, 0, 0)}
		40%,60%{transform: translate3d(+4px, 0, 0)}
		50%{transform: translate3d(-4px, 0, 0)}
	}
	@keyframes cursor-blinks {
		0%{opacity: 1;display: block}
		50%{opacity: 0;display: none}
		100%{opacity: 1;display: block}
	}
</style>